Public Class MarkerCollection

    Private m_markers As ArrayList
    Private m_commentHandler As Marker.GenerateLineComment

    Public Sub New(ByVal source As String, ByVal commentHandler As Marker.GenerateLineComment)
        Me.m_markers = New ArrayList
        Me.m_commentHandler = commentHandler
        Me.ProcessMarkers(source)
    End Sub

    Public Sub New(ByVal commentHandler As Marker.GenerateLineComment)
        Me.m_markers = New ArrayList
        Me.m_commentHandler = commentHandler
    End Sub

    Private Sub ProcessMarkers(ByVal source As String)
        Dim startIndex As Integer = 0
        Dim endIndex As Integer = 0
        While startIndex > -1
            startIndex = GetNextOpenFragment(source, endIndex)
            If startIndex = -1 Then Return
            endIndex = GetNextCloseFragment(source, startIndex)
            If endIndex = -1 Then Return
            endIndex = endIndex + Constants.CMD_CLOSE_METADATA.Length
            Me.m_markers.Add(New Marker(source.Substring(startIndex, endIndex - startIndex), m_commentHandler))
        End While
    End Sub

    Private Shared Function GetNextOpenFragment(ByVal source As String, ByVal startIndex As Integer) As Integer
        Return source.IndexOf(Constants.CMD_OPEN_METADATA, startIndex)
    End Function

    Private Shared Function GetNextCloseFragment(ByVal source As String, ByVal startIndex As Integer) As Integer
        Return source.IndexOf(Constants.CMD_CLOSE_METADATA, startIndex)
    End Function

    Public ReadOnly Property Count() As Integer
        Get
            Return Me.m_markers.Count
        End Get
    End Property

    Default Public ReadOnly Property item(ByVal index As Integer) As Marker
        Get
            Return CType(Me.m_markers(index), Marker)
        End Get
    End Property

    Public Sub AddMarker(ByVal id As String, ByVal source As String)
        Me.m_markers.Add(New Marker(id, source, m_commentHandler))
    End Sub

    Public Function GetMarker(ByVal id As String) As Marker
        For i As Integer = 0 To Me.m_markers.Count - 1
            If [String].Compare(Me(i).ID, id, True) = 0 Then
                Return Me(i)
            End If
        Next
        Return Nothing
    End Function
End Class
